package com.example.hospitalsystem.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.hospitalsystem.exception.HospitalSystemServiceException;
import com.example.hospitalsystem.mapper.*;
import com.example.hospitalsystem.pojo.dto.doctor.*;
import com.example.hospitalsystem.pojo.dto.pharmacy.UpdateMedicineStockDTO;
import com.example.hospitalsystem.pojo.entity.*;
import com.example.hospitalsystem.pojo.vo.PatientPrescriptionPharmacyVO;
import com.example.hospitalsystem.pojo.vo.PrescriptionPharmacyVO;
import com.example.hospitalsystem.result.Result;
import com.example.hospitalsystem.result.ResultCodeEnum;
import com.example.hospitalsystem.service.DoctorService;
import com.example.hospitalsystem.utils.JwtHelper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class DoctorServiceImpl extends ServiceImpl<DoctorMapper, Doctor> implements DoctorService {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private JwtHelper jwtHelper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RegistrationMapper registrationMapper;
    @Autowired
    private PatientMapper patientMapper;
    @Autowired
    private DoctorMapper doctorMapper;
    @Autowired
    private PrescriptionMapper prescriptionMapper;
    @Autowired
    private PrescriptionPharmacyMapper prescriptionPharmacyMapper;
    @Autowired
    private PharmacyMapper pharmacyMapper;
    @Autowired
    private ConsultationMapper consultationMapper;

    @Autowired
    private CaseMapper caseMapper;




    /**
     * 根据患者id查询对应的处方
     * @param consultationId
     * @return
     */
    @Override
    public PatientPrescriptionPharmacyVO selectpPescriptionById(Integer consultationId) {
        LambdaQueryWrapper<Consultation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Consultation::getConsultationId, consultationId);
        Consultation consultation = consultationMapper.selectOne(queryWrapper);
        Patient patient = patientMapper.selectByName(consultation.getPatientName());
        LambdaQueryWrapper<Prescription> prescriptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        prescriptionLambdaQueryWrapper.eq(Prescription::getPatientId, patient.getPatientId());
        Prescription prescription = prescriptionMapper.selectOne(prescriptionLambdaQueryWrapper);
        LambdaQueryWrapper<PrescriptionPharmacy> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PrescriptionPharmacy::getPrescriptionId, prescription.getPrescriptionId());
        List<PrescriptionPharmacy> prescriptionPharmacies = prescriptionPharmacyMapper.selectList(wrapper);
        PatientPrescriptionPharmacyVO vo = new PatientPrescriptionPharmacyVO();
        BeanUtils.copyProperties(prescription, vo);
        List<PrescriptionPharmacy> prescriptionPharmacyList = vo.getPrescriptionPharmacyList();
        for (PrescriptionPharmacy prescriptionPharmacy : prescriptionPharmacies) {
            prescriptionPharmacyList.add(prescriptionPharmacy);
        }
        return vo;
    }

    @Override
    public List<Doctor> searchDoctor(String key) {
        List<Doctor> list = doctorMapper.search(key);
        return list;
    }

    @Override
    public Result<Object> deleteDoctor(int id) {
        LambdaQueryWrapper<Doctor> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Doctor::getDoctorId,id);
        int is_success=baseMapper.delete(lambdaQueryWrapper);
        if(is_success>0){
            return Result.build(null,200,"注销医生成功");
        }else{
            return Result.build(null,200,"注销医生失败");

        }
    }


    /**
     * 医生对患者分配处方/药品
     * @param distributeMedicineDTO
     * @return
     */
    @Override
    @Transactional
    public Result<Object> shareOTCTOPatient(DistributeMedicineDTO distributeMedicineDTO) {

        String token = request.getHeader("Authorization");
        int userId = jwtHelper.getUserId(token);
        LambdaQueryWrapper<Doctor> doctorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        doctorLambdaQueryWrapper.eq(Doctor::getUserId, userId);
        Doctor doctor = doctorMapper.selectOne(doctorLambdaQueryWrapper);

        LambdaQueryWrapper<Patient> patientLambdaQueryWrapper = new LambdaQueryWrapper<>();
        patientLambdaQueryWrapper.eq(Patient::getPatientName, distributeMedicineDTO.getPatientName());
        Patient patient = patientMapper.selectOne(patientLambdaQueryWrapper);

        //向处方表添加数据
        Prescription prescription = new Prescription();
        BeanUtils.copyProperties(distributeMedicineDTO, prescription);
        prescription.setDoctorName(doctor.getDoctorName());
        prescription.setCreateTime(LocalDate.now());
        prescription.setPatientId(patient.getPatientId());
        prescriptionMapper.insert(prescription);

        //减少药品库存参数封装
        List<UpdateMedicineStockDTO> stockDTOS = new ArrayList<>();
        //批量查询药品列表，并向该处方下的关联的药品表开具药品
        List<PrescriptionPharmacyVO> prescriptionPharmacyList = distributeMedicineDTO.getPrescriptionPharmacyList();
        //封装处方/药品关联表
        List<PrescriptionPharmacy> prescriptionPharmacies = new ArrayList<>();
        for (PrescriptionPharmacyVO pp : prescriptionPharmacyList) {
            PrescriptionPharmacy prescriptionPharmacy = new PrescriptionPharmacy();
            BeanUtils.copyProperties(pp, prescriptionPharmacy);
            prescriptionPharmacy.setPrescriptionId(prescription.getPrescriptionId());
            Integer sum;

            if(prescriptionPharmacy.getQuantity() > 1) {
                Integer quantity = prescriptionPharmacy.getQuantity();
                Integer unitPrice = prescriptionPharmacy.getUnitPrice();
                sum = quantity * unitPrice;
                prescriptionPharmacy.setSumPrice(sum);
            } else {
                //数量为1的药品
                prescriptionPharmacy.setSumPrice(prescriptionPharmacy.getUnitPrice());
            }
            prescriptionPharmacies.add(prescriptionPharmacy);

            UpdateMedicineStockDTO dto = new UpdateMedicineStockDTO();
            dto.setMedicineId(prescriptionPharmacy.getMedicineId());
            dto.setQuantity(prescriptionPharmacy.getQuantity());
            stockDTOS.add(dto);
        }
        prescriptionPharmacyMapper.insertBatchMedicine(prescriptionPharmacies);

        //更新药品管理表的药品库存
        //多个药品同时减库存，操作多条sql语句，有一条执行失败，则反馈给都是false
        for (UpdateMedicineStockDTO stockDTO : stockDTOS) {
            int row = pharmacyMapper.updateMedicineStock(stockDTO);
            if (row != 1) {
                throw new HospitalSystemServiceException(ResultCodeEnum.DATABASE_ERROR, "某个药品库存不足");
            }
        }

        return Result.ok(prescriptionPharmacyList, "给患者分配处方/药品成功");
    }

    /**
     * 确认接诊挂号信息,将该条挂号记录从registration挂号表中移除，并存至consultation医生接诊表中
     * @param id
     * @return
     */
    @Override
    @Transactional
    public Result<Object> checkRegistration(Integer id) {
        LambdaQueryWrapper<Registration> registrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        registrationLambdaQueryWrapper.eq(Registration::getRegistrationId, id);
        Registration registration = registrationMapper.selectOne(registrationLambdaQueryWrapper);
        int i = registrationMapper.deleteById(id);
        if(i < 0) {
            throw new HospitalSystemServiceException(ResultCodeEnum.ILLEGAL_OPERATION, "该挂号信息不存在");
        }
        Consultation consultation = new Consultation();
        BeanUtils.copyProperties(registration, consultation);
        consultation.setReceptionStatus(1);
        consultation.setRegistrationTime(registration.getRegistrationTime().toString());
        consultation.setConsultationTime(LocalDate.now());
        consultationMapper.insert(consultation);
        return Result.ok(consultation,"医生确认接诊该挂号，已存至医生接诊表");
    }

    /**
     * 医生移除已缴费患者
     * @param consultationId
     * @return
     */
    @Override
    @Transactional
    public Result<Object> deletePaymentById(Integer consultationId) {
        LambdaQueryWrapper<Consultation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Consultation::getConsultationId, consultationId);
        Consultation consultation = consultationMapper.selectOne(queryWrapper);

        //从接诊表的患者名查询患者信息
        Patient patient = doctorMapper.getPrescriptionByPatientName(consultation.getPatientName());

        if(!Integer.valueOf(1).equals(consultation.getPayStatus())) {
            return Result.build("该患者尚未缴费，请保留其处方信息");
        }

        //根据患者id查询Prescription表数据
        Prescription prescription = doctorMapper.getPrescriptionById(patient.getPatientId());
        //根据处方id删除处方关联的患者药品相关数据
        doctorMapper.deletePatientByPrescriptionId(prescription.getPrescriptionId());
        //根据患者id删除该患者处方表数据
        doctorMapper.deletePrescriptionByPatientId(prescription.getPatientId());
        //删除医生接诊表数据
        doctorMapper.deletePatientByConsultationId(consultationId);

        //添加病例信息

//        Case case1=new Case();
//        Integer patientId=patient.getUserId();
//        LambdaQueryWrapper<Registration>  lambdaQueryWrapper=new LambdaQueryWrapper<>();
//        lambdaQueryWrapper.eq(Registration::getPatientId,patientId);
//
//        LambdaQueryWrapper<Prescription> lambdaQueryWrapper1=new LambdaQueryWrapper<>();
//        lambdaQueryWrapper1.eq(Prescription::getPatientId,patientId);
//
//        Registration registration=registrationMapper.selectOne(lambdaQueryWrapper);
//
//        Prescription prescription1  =prescriptionMapper.selectOne(lambdaQueryWrapper1);
//
////        case1.setDoctorName();
////        case1.getBillingDate();
////        case1.setBornDate();
////        case1.setDiseaseDescription();
////        case1.setRegistrationTime();case1.setMedicineName();
//
//        BeanUtils.copyProperties(registration,case1);
//        BeanUtils.copyProperties(prescription1,case1);
//        caseMapper.insert(case1);

        return Result.ok("缴费患者信息移除成功");

    }

    /**
     * 获取医生个人信息
     * @return
     */
    @Override
    public Result<Object> getInfoByDoctor() {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);
        LambdaQueryWrapper<Doctor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Doctor::getUserId, userId);
        Doctor doctor = doctorMapper.selectOne(queryWrapper);
        return Result.ok(doctor, "获取医生个人信息成功");
    }

    /**
     * 返回医生列表
     * @return
     */
    @Override
    public List<Doctor> getDoctorList() {
        LambdaQueryWrapper<Doctor> queryWrapper = new LambdaQueryWrapper<>();
        List<Doctor> list = doctorMapper.selectList(queryWrapper);
        return list;
    }

    /**
     * 医生分页获取确诊患者信息
     * @param doctorGetPatientDto
     * @return
     */
    @Override
    public Result<Object> doctorGetPatient(DoctorGetPatientDto doctorGetPatientDto) {

        Page<Consultation> consultationPage = new Page<>(doctorGetPatientDto.getPageNum(), doctorGetPatientDto.getPageSize());
        IPage<Consultation> consultationIPage = consultationMapper.selectPage(consultationPage, null);
        return Result.build(consultationIPage, 200, "医生分页查询患者信息成功");
    }

    /**
     * 管理员获取所有医生信息
     * @param doctorPageQueryDto
     * @return
     */
    @Override
    public Result<Object> getAllDoctorInfo(DoctorPageQueryDto doctorPageQueryDto) {

        int pageNum=doctorPageQueryDto.getPageNum();
        int pageSize=doctorPageQueryDto.getPageSize();
        //创建page对象
        Page<Doctor> doctorPage=new Page<>(pageNum,pageSize);
        IPage<Doctor>doctorIPage=doctorMapper.selectPage(doctorPage,null);

        return Result.build(doctorIPage,200,"获取所有管理员信息成功");

    }

    @Override
    public Result<Object> changeDoctorInfo(ChangeDoctorDto changeDoctorDto) {

        LambdaUpdateWrapper<Doctor> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(Doctor::getDoctorId, changeDoctorDto.getDoctorId())
                .set(Doctor::getDepartmentName, changeDoctorDto.getDepartmentName())
                .set(Doctor::getDepartmentKind, changeDoctorDto.getDepartmentKind())
                .set(Doctor::getDoctorIntroduction, changeDoctorDto.getDoctorIntroduction())
                .set(Doctor::getDoctorTitle, changeDoctorDto.getDoctorTitle())
                .set(Doctor::getContact, changeDoctorDto.getContact());
        this.update(lambdaUpdateWrapper);
        return Result.build(null, "更改医生信息成功");
    }

    @Override
    public Result<Object> addDoctorInfo(Doctor doctor) {
        String token = request.getHeader("Authorization");
        int userId = jwtHelper.getUserId(token);

        // 查找用户信息
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getUserId, userId);
        User user = userMapper.selectOne(userLambdaQueryWrapper);

        // 设置医生的userId和doctorPhoto
        doctor.setUserId(userId);
        doctor.setDoctorPhoto(user.getImage());

        // 查找是否已有医生信息
        LambdaQueryWrapper<Doctor> doctorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        doctorLambdaQueryWrapper.eq(Doctor::getUserId, userId);
        Doctor existingDoctor = baseMapper.selectOne(doctorLambdaQueryWrapper);

        if (existingDoctor == null) {
            // 如果医生信息不存在，则插入新的记录
            baseMapper.insert(doctor);
            return Result.build(null, 200, "完善医生信息成功");
        } else {
            // 如果医生信息已存在，则更新记录
            doctor.setDoctorId(existingDoctor.getDoctorId()); // 设置要更新的医生记录的ID
            baseMapper.updateById(doctor);
            return Result.build(null, 200, "更新医生信息成功");
        }
    }


    @Override
    public Result<Object> deleteDoctorInfo(String password) {
        String token = request.getHeader("Authorization");
        int userId = jwtHelper.getUserId(token);
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId, userId);
        User user = userMapper.selectOne(lambdaQueryWrapper);

        if (!user.getPassword().equals(password)) {
            return Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
        }
        int is = userMapper.delete(lambdaQueryWrapper);
        if (is > 0) {
            return Result.build(null, "注销医生信息成功");
        }
        return Result.build(null, "删除信息失败");
    }


    /**
     * 根据id查询医生信息
     * @param doctorId
     * @return
     */
    @Override

    public Result<Object> getDoctorInfoById(Integer doctorId) {
        LambdaQueryWrapper<Doctor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Doctor::getDoctorId, doctorId);
        Doctor doctor = doctorMapper.selectOne(queryWrapper);
        return Result.ok(doctor);
    }



}
